#if defined(ARCTIC)
#if (FEATURE_MODE == 0)
/**
 @file sys_at_monitor.c

 @date 2020-12-15

 @version v1.0

 The file contains AT monitor APIs of sys layer
*/

/***************************************************************
 *
 * Header Files
 *
 ***************************************************************/
#include "sal.h"
#include "ctc_error.h"
#include "ctc_debug.h"

#include "sys_usw_common.h"
#include "sys_usw_monitor.h"
#include "sys_usw_register.h"
#include "sys_usw_interrupt.h"
#include "sys_usw_dma.h"
#include "sys_usw_qos_api.h"
#include "drv_api.h"

extern int32
sys_usw_qos_queue_get(uint8 lchip, ctc_qos_queue_cfg_t* p_que_cfg);
extern int32
_sys_usw_monitor_get_mburst_level(uint8 lchip, uint8 *level, uint64 thrd);
extern int32
sys_usw_get_channel_by_sub_chan(uint8 lchip, uint8 dp_id, uint8 sub_chan, uint16 *channel);
extern int32
sys_at_queue_get_queue_id(uint8 lchip, ctc_qos_queue_id_t* p_queue,uint16* queue_id);
extern int32
sys_at_queue_get_queue_offset(uint8 lchip, ctc_qos_queue_id_t* p_queue, uint8* queue_offset);
extern int32
sys_at_dma_set_monitor_buf_sync_time(uint8 lchip, uint32 interval);
extern int32
sys_at_dma_get_monitor_buf_sync_time(uint8 lchip, uint32* interval);
extern int32
sys_at_qos_queue_get_buffer_watermark(uint8 lchip, uint8 query_pp_id, ctc_qos_queue_id_t *queue, uint32 *uc_cnt);
extern int32
sys_at_qos_queue_clear_buffer_watermark(uint8 lchip, uint8 query_pp_id, ctc_qos_queue_id_t *queue);
extern uint32
sys_at_qos_get_corss_core_tbl_idx(uint8 lchip, uint8 cur_pp_id, uint8 query_pp_id, uint32 shift);
extern uint32
sys_at_qos_get_corss_core_lchip(uint8* lchip_tmp, uint8 cur_pp_id, uint8 query_pp_id);

typedef struct sys_at_monitor_que_buffer_param_s
{
    void* p_reg_base;
    ctc_monitor_data_t* monitor_data;
    ctc_monitor_msg_t** p_msg;
    sys_dma_sync_tbl_t* p_tbl;
    uint32 gport;
    uint8 gchip;
    uint8 value;
}sys_at_monitor_que_buffer_param_t;

STATIC int32
_sys_at_monitor_encode_port_mcq_buffer(uint8 lchip, sys_traverse_t* data)
{
    sys_at_monitor_que_buffer_param_t* p_data = (sys_at_monitor_que_buffer_param_t*)data->data;
    mon_mc_queue_buf_cnt_at_t * p_non_uc_cnt = NULL;
    ctc_monitor_msg_t*  p_msg = *p_data->p_msg;
    uint8 que_id = (data->value3 >> 8) & 0xFF;
    uint8 q_ofst = data->value3 & 0xFF;
    uint8 ofst = (data->value3 >> 16) & 0x1;
    uint8 is_mc = (data->value3 >> 30) & 0x1;

    if (!is_mc)
    {
        return CTC_E_NONE;
    }
    p_non_uc_cnt = (mon_mc_queue_buf_cnt_at_t *)p_data->p_reg_base + q_ofst;
    p_msg->gchip = p_data->gchip;
    p_msg->monitor_type = CTC_MONITOR_BUFFER;
    p_msg->msg_type = CTC_MONITOR_MSG_STATS;
    p_msg->timestamp = (uint64)p_data->p_tbl->ts[1] << 32 | p_data->p_tbl->ts[0];
    p_msg->u.buffer_stats.buffer_type = CTC_MONITOR_BUFFER_QUEUE;
    p_msg->u.buffer_stats.dir = CTC_EGRESS;
    p_msg->u.buffer_stats.uc_cnt = 0;
    p_msg->u.buffer_stats.non_uc_cnt = p_non_uc_cnt->g_0_queueCnt;
    p_msg->u.buffer_stats.buffer_cnt = p_non_uc_cnt->g_0_queueCnt;
    p_msg->u.buffer_stats.gport = p_data->gport;
    p_msg->u.buffer_stats.queue_id.queue_type = CTC_QUEUE_TYPE_NETWORK_EGRESS;
    p_msg->u.buffer_stats.queue_id.queue_id = que_id;
    p_msg->u.buffer_stats.queue_id.class_prio = ofst;
    p_msg->u.buffer_stats.queue_id.gport = p_data->gport;
    p_msg->pp_id = p_data->p_tbl->pp_id;
    *p_data->p_msg += 1;
    p_data->monitor_data->msg_num++;
    return CTC_E_NONE;
}

STATIC int32
_sys_at_monitor_port_ucq_cmp(uint8 lchip, sys_traverse_t* data)
{
    sys_at_monitor_que_buffer_param_t* p_data = (sys_at_monitor_que_buffer_param_t*)data->data;
    uint8 que_id = (data->value3 >> 8) & 0xFF;
    uint8 q_ofst = data->value3 & 0xFF;
    uint8 is_mc = (data->value3 >> 30) & 0x1;

    if (!is_mc && (p_data->value == q_ofst))
    {
        p_data->value = que_id;
        return CTC_E_EXIST;
    }
    return CTC_E_NONE;
}

int32
sys_at_monitor_sync_latency(uint8 lchip, ctc_monitor_data_t *p_data,
                                     void* p_latency_param, uint64* p_ts)
{
     uint8 info_type = 0;
     uint16 channel_id = 0;
     uint8 idx = 0;
     uint8 gchip = 0;
     uint16 lport = 0;
     uint16 gport = 0;
     ctc_monitor_msg_t *p_msg = NULL;
     ms_latency_mon_dma_info_at_t *p_latency = (ms_latency_mon_dma_info_at_t *)p_latency_param;

     p_msg =  (ctc_monitor_msg_t*)p_data->p_msg + p_data->msg_num;
     p_msg->monitor_type = CTC_MONITOR_LATENCY;
     p_msg->timestamp = *p_ts;
     sys_usw_get_gchip_id(lchip, &gchip);
     p_msg->gchip = gchip;
     channel_id = p_latency->u.event.channelId;
     /*Need mapping from channel to lport*/
     lport = SYS_MAP_SYS_LPORT_TO_DRV_LPORT(SYS_GET_LPORT_ID_WITH_CHAN(lchip, 0, channel_id));
     gport = SYS_MAP_DRV_LPORT_TO_CTC_GPORT(gchip, lport);

     info_type = p_latency->u.event.infoType;

     if (0 == info_type)
     {
         p_msg->msg_type = CTC_MONITOR_MSG_STATS;
         p_msg->u.latency_stats.gport = gport;
         p_msg->u.latency_stats.threshold_cnt[0] = p_latency->u.mon.latencyThrdCnt0_31_22 << 22 | p_latency->u.mon.latencyThrdCnt0_21_0;
         p_msg->u.latency_stats.threshold_cnt[1] = p_latency->u.mon.latencyThrdCnt1_31_22 << 22 | p_latency->u.mon.latencyThrdCnt1_21_0;
         p_msg->u.latency_stats.threshold_cnt[2] = p_latency->u.mon.latencyThrdCnt2_31_22 << 22 | p_latency->u.mon.latencyThrdCnt2_21_0;
         p_msg->u.latency_stats.threshold_cnt[3] = p_latency->u.mon.latencyThrdCnt3_31_22 << 22 | p_latency->u.mon.latencyThrdCnt3_21_0;
         p_msg->u.latency_stats.threshold_cnt[4] = p_latency->u.mon.latencyThrdCnt4_31_22 << 22 | p_latency->u.mon.latencyThrdCnt4_21_0;
         p_msg->u.latency_stats.threshold_cnt[5] = p_latency->u.mon.latencyThrdCnt5_31_22 << 22 | p_latency->u.mon.latencyThrdCnt5_21_0;
         p_msg->u.latency_stats.threshold_cnt[6] = p_latency->u.mon.latencyThrdCnt6_31_22 << 22 | p_latency->u.mon.latencyThrdCnt6_21_0;
         p_msg->u.latency_stats.threshold_cnt[7] = p_latency->u.mon.latencyThrdCnt7_31_22 << 22 | p_latency->u.mon.latencyThrdCnt7_21_0;

         for (idx = 0; idx < 8; idx++)
         {
             p_usw_monitor_master[lchip]->latency_stats[channel_id][idx] += p_msg->u.latency_stats.threshold_cnt[idx];
         }
     }
     else
     {
         p_msg->msg_type = CTC_MONITOR_MSG_EVENT;
         p_msg->u.latency_event.gport = gport;
         p_msg->u.latency_event.event_state = p_latency->u.event.valid;
         p_msg->u.latency_event.source_port = SYS_MAP_DRV_GPORT_TO_CTC_GPORT(p_latency->u.event.sourcePort);
         p_msg->u.latency_event.port = p_latency->u.event.localPhyPort;
         p_msg->u.latency_event.level = p_latency->u.event.region;
         p_msg->u.latency_event.event_state = (p_msg->u.latency_event.event_state == 1) ? CTC_MONITOR_EVENT_STATE_OCCUR:CTC_MONITOR_EVENT_STATE_CLEAR;
         p_msg->u.latency_event.latency = ((uint64)p_latency->u.event.residenceTime_47_41 << 41) | ((uint64)p_latency->u.event.residenceTime_40_9 << 9) | p_latency->u.event.residenceTime_8_0;
         p_msg->timestamp = ((uint64)p_latency->u.event.timestamp_63_41 << 41) | ((uint64)p_latency->u.event.timestamp_40_9 << 9) | p_latency->u.event.timestamp_8_0;
     }

     p_data->msg_num++;
    return CTC_E_NONE;
}

int32
sys_at_monitor_sync_buffer(uint8 lchip, ctc_monitor_data_t *p_data,
                                   void* p_buffer_param, uint64* p_ts)
{
    ctc_monitor_msg_t *p_msg = NULL;
    ms_erm_mb_info_at_t *p_buffer = (ms_erm_mb_info_at_t *)p_buffer_param;
    uint32 field_val = 0;
    uint32 buffer_cnt = 0;
    uint64 timestamp = 0;
    int32 ret = 0;
    uint16 lport = 0;
    uint16 channel_id = 0;
    uint16 gport = 0;
    uint8 msg_idx = 0;
    uint8 gchip = 0;
    uint8 burst_type = 0;
    uint8 level = 0;
    uint8 idx = 0;

    msg_idx = p_data->msg_num;
    p_msg = (ctc_monitor_msg_t*)p_data->p_msg +msg_idx;
    p_msg->monitor_type = CTC_MONITOR_BUFFER;
    CTC_ERROR_RETURN(sys_usw_get_gchip_id(lchip, &gchip));
    p_msg->gchip = gchip;
    p_msg->msg_type = CTC_MONITOR_MSG_EVENT;
    p_msg->timestamp = *p_ts;
    p_msg->pp_id = lchip - SYS_PP_BASE(lchip);
    burst_type = p_buffer->microburstType_2;
    burst_type = (burst_type << 2) | p_buffer->u.data.microburstType_1_0;
    switch(burst_type)
    {
    case 1:
        sys_usw_get_channel_by_sub_chan(lchip, p_buffer->u.channel.dpId & 0x1,
                                        (uint8)(p_buffer->u.channel.channelId),
                                        &channel_id);
        /*Need mapping from channel to lport*/
        lport = SYS_GET_LPORT_ID_WITH_CHAN(lchip, 0, channel_id);
        lport = SYS_MAP_SYS_LPORT_TO_DRV_LPORT(lport);
        gport = SYS_MAP_DRV_LPORT_TO_CTC_GPORT(gchip, lport);
        p_msg->u.buffer_event.gport = gport;
        p_msg->u.buffer_event.buffer_type = CTC_MONITOR_BUFFER_PORT;
        p_msg->u.buffer_event.uc_cnt = p_buffer->u.channel.ucastBufCnt;
        field_val = p_usw_monitor_master[lchip]->mb_thrd->port_thrd[channel_id][1];
        buffer_cnt = p_msg->u.buffer_event.uc_cnt;
        p_msg->u.buffer_event.event_state = (buffer_cnt >= field_val) ? CTC_MONITOR_EVENT_STATE_OCCUR:CTC_MONITOR_EVENT_STATE_CLEAR;
        break;
     case 2:
        p_msg->u.buffer_event.buffer_type = CTC_MONITOR_BUFFER_TOTAL;
        p_msg->u.buffer_event.buffer_cnt = p_buffer->u.total.totalCnt;
        field_val = p_usw_monitor_master[lchip]->mb_thrd->total_thrd[1];
        buffer_cnt = p_msg->u.buffer_event.buffer_cnt;
        p_msg->u.buffer_event.event_state = (buffer_cnt >= field_val) ? CTC_MONITOR_EVENT_STATE_OCCUR:CTC_MONITOR_EVENT_STATE_CLEAR;
        break;
     case 3:
        p_msg->u.buffer_event.buffer_type = CTC_MONITOR_BUFFER_SC;
        p_msg->u.buffer_event.buffer_cnt =  p_buffer->u.sc.scCnt;
        p_msg->u.buffer_event.sc = p_buffer->u.sc.id;
        field_val = p_usw_monitor_master[lchip]->mb_thrd->sc_thrd[p_buffer->u.sc.id][1];
        buffer_cnt = p_msg->u.buffer_event.buffer_cnt;
        p_msg->u.buffer_event.event_state = (buffer_cnt >= field_val) ? CTC_MONITOR_EVENT_STATE_OCCUR:CTC_MONITOR_EVENT_STATE_CLEAR;
        break;
     case 4:
        p_msg->u.buffer_event.buffer_type = CTC_MONITOR_BUFFER_CONTROL;
        p_msg->u.buffer_event.buffer_cnt =  p_buffer->u.critical.criticalCnt;
        field_val = p_usw_monitor_master[lchip]->mb_thrd->critical_thrd[1];
        buffer_cnt = p_msg->u.buffer_event.buffer_cnt;
        p_msg->u.buffer_event.event_state = (buffer_cnt >= field_val) ? CTC_MONITOR_EVENT_STATE_OCCUR:CTC_MONITOR_EVENT_STATE_CLEAR;
        break;
     case 5:
        p_msg->u.buffer_event.buffer_type = CTC_MONITOR_BUFFER_C2C;
        p_msg->u.buffer_event.buffer_cnt =  p_buffer->u.c2c.c2cCnt;
        field_val = p_usw_monitor_master[lchip]->mb_thrd->c2c_thrd[1];
        buffer_cnt = p_msg->u.buffer_event.buffer_cnt;
        p_msg->u.buffer_event.event_state = (buffer_cnt >= field_val) ? CTC_MONITOR_EVENT_STATE_OCCUR:CTC_MONITOR_EVENT_STATE_CLEAR;
        break;
     case 6:
        sys_usw_get_channel_by_sub_chan(lchip, p_buffer->u.channel.dpId & 0x1,
                                        (uint8)(p_buffer->u.channel.channelId),
                                        &channel_id);
        /*Need mapping from channel to lport*/
        lport = SYS_GET_LPORT_ID_WITH_CHAN(lchip, 0, channel_id);
        lport = SYS_MAP_SYS_LPORT_TO_DRV_LPORT(lport);
        gport = SYS_MAP_DRV_LPORT_TO_CTC_GPORT(gchip, lport);
        p_msg->u.buffer_event.gport = gport;
        p_msg->u.buffer_event.buffer_type = CTC_MONITOR_BUFFER_PORT_PRIO_CLASS;
        p_msg->u.buffer_event.uc_cnt =  p_buffer->u.channel.ucastBufCnt;
        p_msg->u.buffer_event.sc = p_buffer->u.channel.tc;
        level = CTC_BMP_ISSET(p_usw_monitor_master[lchip]->mb_thrd->porttc_lvl_bmp, channel_id*SYS_MONITOR_PRIO_CLASS_NUM + p_buffer->u.channel.tc) ? 1:0;
        field_val = p_usw_monitor_master[lchip]->mb_thrd->porttc_thrd[channel_id * SYS_MONITOR_PRIO_CLASS_LEVEL_NUM + level][1];
        buffer_cnt = p_msg->u.buffer_event.uc_cnt;
        p_msg->u.buffer_event.event_state = (buffer_cnt >= field_val) ? CTC_MONITOR_EVENT_STATE_OCCUR:CTC_MONITOR_EVENT_STATE_CLEAR;
        break;

     case 7:
        /*7: cross core*/
        if (lchip < (SYS_PP_BASE(lchip) + PP_NUM_PER_CORE))
        {
            p_msg->pp_id += PP_NUM_PER_CORE;
        }
        else if (lchip > (SYS_PP_BASE(lchip) + PP_NUM_PER_CORE))
        {
            p_msg->pp_id -= PP_NUM_PER_CORE;
        }
     default:/*sync stats*/
     {
        sys_at_monitor_que_buffer_param_t param;
        /*0: self core*/
        p_msg->msg_type = CTC_MONITOR_MSG_STATS;
        sys_usw_get_channel_by_sub_chan(lchip, p_buffer->u.mon.dpId & 0x1,
                                        (uint8)(p_buffer->u.mon.channelId),
                                        &channel_id);
        /*Need mapping from channel to lport*/
        lport = SYS_GET_LPORT_ID_WITH_CHAN(lchip, 0, channel_id);
        lport = SYS_MAP_SYS_LPORT_TO_DRV_LPORT(lport);
        gport = SYS_MAP_DRV_LPORT_TO_CTC_GPORT(gchip, lport);
        p_msg->u.buffer_stats.gport = gport;
        p_msg->u.buffer_stats.dir = CTC_EGRESS;
        switch (p_buffer->u.mon.subType)
        {
        case 2:
            if (!p_usw_monitor_master[lchip]->buf_scan->port[lport].queue_en)
            {
                return CTC_E_NONE; /*return to next*/
            }
            /*need continue unused queue*/
            param.value = p_buffer->u.mon.offset;
            ret = sys_usw_queue_traverse_queue_node(lchip, lport, _sys_at_monitor_port_ucq_cmp, &param);
            if (ret != CTC_E_EXIST)
            {
               return CTC_E_NONE;
            }
            p_msg->u.buffer_stats.buffer_type = CTC_MONITOR_BUFFER_QUEUE;
            p_msg->u.buffer_stats.queue_id.queue_type = CTC_QUEUE_TYPE_NETWORK_EGRESS;
            p_msg->u.buffer_stats.queue_id.gport = gport;
            p_msg->u.buffer_stats.queue_id.queue_id = param.value;
            break;
        case 1:
            if (!p_usw_monitor_master[lchip]->buf_scan->port[lport].port_sc_en_egs)
            {
                return CTC_E_NONE; /*return to next*/
            }
            p_msg->u.buffer_stats.buffer_type = CTC_MONITOR_BUFFER_PORT_SC;
            p_msg->u.buffer_stats.sc = p_buffer->u.mon.offset;
            break;
        case 0:
            if (!p_usw_monitor_master[lchip]->buf_scan->port[lport].port_en_egs)
            {
                return CTC_E_NONE; /*return to next*/
            }
            p_msg->u.buffer_stats.buffer_type = CTC_MONITOR_BUFFER_PORT;
            break;
        default:
            return CTC_E_NONE; /*return to next*/
        }
        p_msg->u.buffer_stats.non_uc_cnt = 0;
        p_msg->u.buffer_stats.uc_cnt = p_buffer->u.mon.resrcCnt;
        p_msg->u.buffer_stats.buffer_cnt = p_buffer->u.mon.resrcCnt;
     }
        break;
    }

    msg_idx++;

    if (CTC_MONITOR_MSG_EVENT == p_msg->msg_type)
    {
        if (p_msg->u.buffer_event.event_state == CTC_MONITOR_EVENT_STATE_OCCUR && p_msg->u.buffer_event.buffer_type == CTC_MONITOR_BUFFER_PORT)
        {
            p_usw_monitor_master[lchip]->mburst_timestamp[lport] = p_msg->timestamp;
        }
        else if (p_msg->u.buffer_event.event_state == CTC_MONITOR_EVENT_STATE_CLEAR && p_msg->u.buffer_event.buffer_type == CTC_MONITOR_BUFFER_PORT)
        {
            timestamp = p_msg->timestamp - p_usw_monitor_master[lchip]->mburst_timestamp[lport];
            _sys_usw_monitor_get_mburst_level(lchip, &level, timestamp);
            if (level != 0xff)
            {
                p_msg = (ctc_monitor_msg_t *)p_data->p_msg + msg_idx;
                p_msg->monitor_type = CTC_MONITOR_BUFFER;
                p_msg->msg_type = CTC_MONITOR_MSG_MBURST_STATS;
                p_msg->timestamp = *p_ts;
                p_usw_monitor_master[lchip]->mburst_stats[channel_id][level]++;
                p_msg->u.mburst_stats.gport = gport;
                for (idx = 0; idx < 8; idx++)
                {
                    p_msg->u.mburst_stats.threshold_cnt[idx] = p_usw_monitor_master[lchip]->mburst_stats[channel_id][idx];
                }
                msg_idx++;
            }
        }
    }

    p_data->msg_num = msg_idx;

    return CTC_E_NONE;
}


int32
sys_at_monitor_buf_sync_data(uint8 lchip, void* p_data)
{
    uint16 entry_num = 0;
    uint16 index = 0;
    uint8* p_monitor = NULL;
    sys_dma_info_t* p_dma_info = (sys_dma_info_t*)p_data;
    ctc_monitor_data_t  monitor_data;
    cpu_info_at_t* p_cpu_info = NULL;
    ms_erm_dma_info_at_t* p_erm_mon = NULL;
    uint32 ds[2] = {0};
    uint64 ts;
    uint8 ii = 0;
    uint8 info_idx = 0;
    uint8 pp_id = 0;

    sal_memset(&monitor_data, 0, sizeof(monitor_data));

    monitor_data.p_msg = p_usw_monitor_master[lchip]->p_buffer;
    entry_num = p_dma_info->entry_num;
    p_monitor = ((uint8*)p_dma_info->p_data);

    for (index = 0; index < entry_num; index++)
    {
        p_cpu_info = (cpu_info_at_t*)p_monitor;
        ts = (uint64)p_cpu_info->timestamp_63_32 << 32 | p_cpu_info->timestamp_31_0;
        p_erm_mon = (ms_erm_dma_info_at_t*)SYS_USW_DMA_GET_INFO_ADDR(lchip, p_monitor);

        /*buffer event & buffer stats(erm portuc/portscuc/queue/uc)*/
        for (ii = 0; ii < p_erm_mon->info_num; ii++)/*info num max g15->g0 */
        {
            info_idx = 15 - ii;
            /*
            ds[0] = (p_erm_mon->data[info_idx] >> info_idx) | ((p_erm_mon->data[info_idx + 1] & ((1 << info_idx) - 1)) << (32 - info_idx));
            ds[1] = (p_erm_mon->data[info_idx + 1] >> info_idx) & 0x1;
            */
            GetDsBsErmToDma(A, g_0_mbInfo_f + info_idx, p_erm_mon, ds);
            pp_id = GetDsBsErmToDma(V, g_0_ppId_f + info_idx, p_erm_mon);
            sys_at_monitor_sync_buffer(lchip + pp_id, &monitor_data, (void*)&ds, &ts);
            /*CallBack*/
            if (monitor_data.msg_num >= MCHIP_CAP(SYS_CAP_MONITOR_SYNC_CNT))
            {
                if (p_usw_monitor_master[lchip]->func)
                {
                    p_usw_monitor_master[lchip]->func(&monitor_data, p_usw_monitor_master[lchip]->user_data);
                }
                monitor_data.p_msg = p_usw_monitor_master[lchip]->p_buffer;
                monitor_data.msg_num = 0;
            }
        }
        p_monitor += sizeof(CpuInfoMicroBurstMon_m);
    }

    /*CallBack*/
    if (p_usw_monitor_master[lchip]->func && monitor_data.msg_num)
    {
        p_usw_monitor_master[lchip]->func(&monitor_data, p_usw_monitor_master[lchip]->user_data);
    }

    return CTC_E_NONE;
}

int32
sys_at_monitor_latency_sync_data(uint8 lchip, void* p_data)
{
    uint16 entry_num = 0;
    uint16 index = 0;
    uint8* p_monitor = NULL;
    sys_dma_info_t* p_dma_info = (sys_dma_info_t*)p_data;
    ctc_monitor_data_t  monitor_data;
    cpu_info_at_t* p_cpu_info = NULL;
    ms_latency_mon_dma_info_at_t* p_latency_mon = NULL;
    uint64 ts;

    sal_memset(&monitor_data, 0, sizeof(monitor_data));

    monitor_data.p_msg = p_usw_monitor_master[lchip]->p_latency;
    entry_num = p_dma_info->entry_num;
    p_monitor = ((uint8*)p_dma_info->p_data);
    for (index = 0; index < entry_num; index++)
    {
        p_cpu_info = (cpu_info_at_t*)p_monitor;
        ts = (uint64)p_cpu_info->timestamp_63_32 << 32 | p_cpu_info->timestamp_31_0;

        p_latency_mon = (ms_latency_mon_dma_info_at_t*)SYS_USW_DMA_GET_INFO_ADDR(lchip, p_monitor);
        sys_at_monitor_sync_latency(lchip, &monitor_data, p_latency_mon, &ts);

        p_monitor += DRV_TABLE_ENTRY_SIZE(lchip, CpuInfoLatencyMon_t);
        /*CallBack*/
        if (monitor_data.msg_num >= MCHIP_CAP(SYS_CAP_MONITOR_SYNC_CNT))
        {
            if (p_usw_monitor_master[lchip]->func)
            {
                p_usw_monitor_master[lchip]->func(&monitor_data, p_usw_monitor_master[lchip]->user_data);
            }
            monitor_data.p_msg = p_usw_monitor_master[lchip]->p_latency;
            monitor_data.msg_num = 0;
        }
    }
    /*CallBack*/
    if (p_usw_monitor_master[lchip]->func && monitor_data.msg_num)
    {
        p_usw_monitor_master[lchip]->func(&monitor_data, p_usw_monitor_master[lchip]->user_data);
    }

    return CTC_E_NONE;
}

#define SYS_AT_ENCODE_BUF_STATS_MSG(TYPE, DIR, DATA, IS_UC)                 \
{                                                                           \
            p_msg->gchip = gchip;                                           \
            p_msg->monitor_type = CTC_MONITOR_BUFFER;                       \
            p_msg->msg_type = CTC_MONITOR_MSG_STATS;                        \
            p_msg->timestamp = ts;                                          \
            p_msg->u.buffer_stats.buffer_type = TYPE;                       \
            p_msg->u.buffer_stats.dir = DIR;                                \
            p_msg->u.buffer_stats.uc_cnt = (IS_UC) ? (DATA) : 0;            \
            p_msg->u.buffer_stats.non_uc_cnt = (IS_UC) ?  0 : (DATA);          \
            p_msg->u.buffer_stats.buffer_cnt = DATA;                        \
            p_msg->pp_id = p_tbl->pp_id;                                    \
            p_msg += 1;                                                     \
            monitor_data->msg_num++;                                        \
}

#define SYS_AT_ENCODE_BUF_STATS_MSG_SC(SC, DIR, DATA, IS_UC)                \
{                                                                           \
            p_msg->gchip = gchip;                                           \
            p_msg->monitor_type = CTC_MONITOR_BUFFER;                       \
            p_msg->msg_type = CTC_MONITOR_MSG_STATS;                        \
            p_msg->timestamp = ts;                                          \
            p_msg->u.buffer_stats.buffer_type = CTC_MONITOR_BUFFER_SC;      \
            p_msg->u.buffer_stats.dir = DIR;                                \
            p_msg->u.buffer_stats.uc_cnt = (IS_UC) ? (DATA) : 0;            \
            p_msg->u.buffer_stats.non_uc_cnt = (IS_UC) ?  0 : (DATA);          \
            p_msg->u.buffer_stats.buffer_cnt = DATA;                        \
            p_msg->u.buffer_stats.sc = SC;                                  \
            p_msg->pp_id = p_tbl->pp_id;                                    \
            p_msg += 1;                                                     \
            monitor_data->msg_num++;                                         \
}

#define SYS_AT_ENCODE_BUF_STATS_MSG_PORT(PORT, DIR, DATA, IS_UC)                \
{                                                                           \
            p_msg->gchip = gchip;                                           \
            p_msg->monitor_type = CTC_MONITOR_BUFFER;                       \
            p_msg->msg_type = CTC_MONITOR_MSG_STATS;                        \
            p_msg->timestamp = ts;                                          \
            p_msg->u.buffer_stats.buffer_type = CTC_MONITOR_BUFFER_PORT;      \
            p_msg->u.buffer_stats.dir = DIR;                                \
            p_msg->u.buffer_stats.uc_cnt = (IS_UC) ? (DATA) : 0;            \
            p_msg->u.buffer_stats.non_uc_cnt = (IS_UC) ?  0 : (DATA);          \
            p_msg->u.buffer_stats.buffer_cnt = DATA;                        \
            p_msg->u.buffer_stats.gport = PORT;                             \
            p_msg->pp_id = p_tbl->pp_id;                                    \
            p_msg += 1;                                                     \
            monitor_data.msg_num++;                                         \
}

#define SYS_AT_ENCODE_BUF_STATS_MSG_PORT_TC(PORT, DIR, TC, DATA, IS_UC)                \
{                                                                           \
            p_msg->gchip = gchip;                                           \
            p_msg->monitor_type = CTC_MONITOR_BUFFER;                       \
            p_msg->msg_type = CTC_MONITOR_MSG_STATS;                        \
            p_msg->timestamp = ts;                                          \
            p_msg->u.buffer_stats.buffer_type = CTC_MONITOR_BUFFER_PORT_PRIO_CLASS;      \
            p_msg->u.buffer_stats.dir = DIR;                         \
            p_msg->u.buffer_stats.sc = TC;                                \
            p_msg->u.buffer_stats.uc_cnt = (IS_UC) ? (DATA) : 0;            \
            p_msg->u.buffer_stats.non_uc_cnt = (IS_UC) ?  0 : (DATA);          \
            p_msg->u.buffer_stats.buffer_cnt = DATA;                        \
            p_msg->u.buffer_stats.gport = PORT;                             \
            p_msg->pp_id = p_tbl->pp_id;                                    \
            p_msg += 1;                                                     \
            monitor_data.msg_num++;                                         \
}

#define SYS_AT_ENCODE_BUF_STATS_MSG_PORT_SC(PORT, DIR, SC, DATA, IS_UC)          \
{                                                                           \
            p_msg->gchip = gchip;                                           \
            p_msg->monitor_type = CTC_MONITOR_BUFFER;                       \
            p_msg->msg_type = CTC_MONITOR_MSG_STATS;                        \
            p_msg->timestamp = ts;                                          \
            p_msg->u.buffer_stats.buffer_type = CTC_MONITOR_BUFFER_PORT_SC; \
            p_msg->u.buffer_stats.dir = DIR;                                 \
            p_msg->u.buffer_stats.sc = SC;                                  \
            p_msg->u.buffer_stats.uc_cnt = (IS_UC) ? (DATA) : 0;            \
            p_msg->u.buffer_stats.non_uc_cnt = (IS_UC) ?  0 : (DATA);          \
            p_msg->u.buffer_stats.buffer_cnt = DATA;                        \
            p_msg->u.buffer_stats.gport = PORT;                             \
            p_msg->pp_id = p_tbl->pp_id;                                    \
            p_msg += 1;                                                     \
            monitor_data.msg_num++;                                         \
}

#define SYS_AT_BUFFER_STATS_REPORT(CNT)                                                             \
    if (((monitor_data.msg_num + (CNT)) > MCHIP_CAP(SYS_CAP_MONITOR_SYNC_CNT))                      \
          && p_usw_monitor_master[lchip]->func)                                                     \
    {                                                                                               \
        p_usw_monitor_master[lchip]->func(&monitor_data, p_usw_monitor_master[lchip]->user_data);   \
        monitor_data.msg_num = 0;                                                                   \
        p_msg = monitor_data.p_msg;                                                                 \
    }

#define SYS_AT_ENCODE_SNAPSHOT_BUF_STATS_MSG(TYPE, DIR, DATA, IS_UC)        \
{                                                                           \
            p_msg->gchip = gchip;                                           \
            p_msg->monitor_type = CTC_MONITOR_BUFFER;                       \
            p_msg->msg_type = CTC_MONITOR_MSG_STATS;                        \
            p_msg->u.buffer_stats.buffer_type = TYPE;                       \
            p_msg->u.buffer_stats.dir = DIR;                                \
            p_msg->u.buffer_stats.uc_cnt = (IS_UC) ? (DATA) : 0;            \
            p_msg->u.buffer_stats.non_uc_cnt = (IS_UC) ?  0 : (DATA);       \
            p_msg->u.buffer_stats.buffer_cnt = DATA;                        \
            p_msg->pp_id = lchip - SYS_PP_BASE(lchip);                      \
            p_msg += 1;                                                     \
            info.msg_num++;                                                 \
}

#define SYS_AT_ENCODE_SNAPSHOT_BUF_STATS_MSG_SC(SC, DIR, DATA, IS_UC)       \
{                                                                           \
            p_msg->gchip = gchip;                                           \
            p_msg->monitor_type = CTC_MONITOR_BUFFER;                       \
            p_msg->msg_type = CTC_MONITOR_MSG_STATS;                        \
            p_msg->u.buffer_stats.buffer_type = CTC_MONITOR_BUFFER_SC;      \
            p_msg->u.buffer_stats.dir = DIR;                                \
            p_msg->u.buffer_stats.uc_cnt = (IS_UC) ? (DATA) : 0;            \
            p_msg->u.buffer_stats.non_uc_cnt = (IS_UC) ?  0 : (DATA);       \
            p_msg->u.buffer_stats.buffer_cnt = DATA;                        \
            p_msg->u.buffer_stats.sc = SC;                                  \
            p_msg->pp_id = lchip - SYS_PP_BASE(lchip);                      \
            p_msg += 1;                                                     \
            info.msg_num++;                                                 \
}

#define SYS_AT_MC_Q_NUM 6
#define SYS_AT_TC_NUM 8

int32
sys_at_monitor_sync_global_buffer_stats(uint8 lchip, uint8 gchip, ctc_monitor_data_t*  monitor_data, sys_dma_sync_tbl_t* p_tbl, uint64 ts)
{
    uint32 cmd = 0;
    uint32 field_val = 0;
    mon_buf_misc_cnt_at_t misc_cnt_uc;
    mon_buf_misc_cnt_at_t misc_cnt_mc;
    mon_egs_buf_misc_cnt_mc_at_t misc_egs_cnt_mc;
    mon_buf_sc_cnt_at_t sc_cnt;
    mon_egs_buf_sc_cnt_mc_at_t sc_egs_cnt_mc;
    ctc_monitor_msg_t* p_msg = monitor_data->p_msg;

    if (p_usw_monitor_master[lchip]->buf_scan->total_en_igs
         ||p_usw_monitor_master[lchip]->buf_scan->c2c_en_igs
         ||p_usw_monitor_master[lchip]->buf_scan->critical_en_igs)
    {
        cmd = DRV_IOR(DsIrmMiscCntUc_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &misc_cnt_uc);

        cmd = DRV_IOR(DsIrmMiscCntMc_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &misc_cnt_mc);
        if (p_usw_monitor_master[lchip]->buf_scan->total_en_igs)
        {
            SYS_AT_ENCODE_BUF_STATS_MSG(CTC_MONITOR_BUFFER_TOTAL, CTC_INGRESS, misc_cnt_uc.totalCnt, 1);
            SYS_AT_ENCODE_BUF_STATS_MSG(CTC_MONITOR_BUFFER_TOTAL, CTC_INGRESS, misc_cnt_mc.totalCnt, 0);
        }
        if (p_usw_monitor_master[lchip]->buf_scan->c2c_en_igs)
        {
            SYS_AT_ENCODE_BUF_STATS_MSG(CTC_MONITOR_BUFFER_C2C, CTC_INGRESS, misc_cnt_uc.c2cCnt, 1);
            SYS_AT_ENCODE_BUF_STATS_MSG(CTC_MONITOR_BUFFER_C2C, CTC_INGRESS, misc_cnt_mc.c2cCnt, 0);
        }
        if (p_usw_monitor_master[lchip]->buf_scan->critical_en_igs)
        {
            SYS_AT_ENCODE_BUF_STATS_MSG(CTC_MONITOR_BUFFER_CONTROL, CTC_INGRESS, misc_cnt_uc.criticalCnt, 1);
            SYS_AT_ENCODE_BUF_STATS_MSG(CTC_MONITOR_BUFFER_CONTROL, CTC_INGRESS, misc_cnt_mc.criticalCnt, 0);
        }
    }
    if (p_usw_monitor_master[lchip]->buf_scan->total_en_egs
         ||p_usw_monitor_master[lchip]->buf_scan->c2c_en_egs
         ||p_usw_monitor_master[lchip]->buf_scan->critical_en_egs
         ||p_usw_monitor_master[lchip]->buf_scan->span_en)
    {
        cmd = DRV_IOR(DsErmMiscCntUc_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &misc_cnt_uc);

        cmd = DRV_IOR(DsErmMiscCntMc_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &misc_egs_cnt_mc);
        if (p_usw_monitor_master[lchip]->buf_scan->total_en_egs)
        {
            SYS_AT_ENCODE_BUF_STATS_MSG(CTC_MONITOR_BUFFER_TOTAL, CTC_EGRESS, misc_cnt_uc.totalCnt, 1);
            SYS_AT_ENCODE_BUF_STATS_MSG(CTC_MONITOR_BUFFER_TOTAL, CTC_EGRESS, misc_egs_cnt_mc.g_0_totalCnt, 0);
        }
        if (p_usw_monitor_master[lchip]->buf_scan->c2c_en_egs)
        {
            SYS_AT_ENCODE_BUF_STATS_MSG(CTC_MONITOR_BUFFER_C2C, CTC_EGRESS, misc_cnt_uc.c2cCnt, 1);
            SYS_AT_ENCODE_BUF_STATS_MSG(CTC_MONITOR_BUFFER_C2C, CTC_EGRESS, misc_egs_cnt_mc.g_0_c2cCnt, 0);
        }
        if (p_usw_monitor_master[lchip]->buf_scan->critical_en_egs)
        {
            SYS_AT_ENCODE_BUF_STATS_MSG(CTC_MONITOR_BUFFER_CONTROL, CTC_EGRESS, misc_cnt_uc.criticalCnt, 1);
            SYS_AT_ENCODE_BUF_STATS_MSG(CTC_MONITOR_BUFFER_CONTROL, CTC_EGRESS, misc_egs_cnt_mc.g_0_criticalCnt, 0);
        }
        if (p_usw_monitor_master[lchip]->buf_scan->span_en)
        {
            SYS_AT_ENCODE_BUF_STATS_MSG(CTC_MONITOR_BUFFER_SPAN, CTC_EGRESS, misc_egs_cnt_mc.g_0_spanCnt, 0);
        }
    }
    if (p_usw_monitor_master[lchip]->buf_scan->sc_en_igs)
    {
        cmd = DRV_IOR(DsIrmScCntUc_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &sc_cnt);
        SYS_AT_ENCODE_BUF_STATS_MSG_SC(0, CTC_INGRESS, sc_cnt.scCnt0, 1);
        SYS_AT_ENCODE_BUF_STATS_MSG_SC(1, CTC_INGRESS, sc_cnt.scCnt1, 1);
        SYS_AT_ENCODE_BUF_STATS_MSG_SC(2, CTC_INGRESS, sc_cnt.scCnt2, 1);
        SYS_AT_ENCODE_BUF_STATS_MSG_SC(3, CTC_INGRESS, sc_cnt.scCnt3, 1);


        cmd = DRV_IOR(DsIrmScCntMc_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &sc_cnt);
        SYS_AT_ENCODE_BUF_STATS_MSG_SC(0, CTC_INGRESS, sc_cnt.scCnt0, 0);
        SYS_AT_ENCODE_BUF_STATS_MSG_SC(1, CTC_INGRESS, sc_cnt.scCnt1, 0);
        SYS_AT_ENCODE_BUF_STATS_MSG_SC(2, CTC_INGRESS, sc_cnt.scCnt2, 0);
        SYS_AT_ENCODE_BUF_STATS_MSG_SC(3, CTC_INGRESS, sc_cnt.scCnt3, 0);
    }
    if (p_usw_monitor_master[lchip]->buf_scan->sc_en_egs)
    {
        cmd = DRV_IOR(DsErmScCntUc_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &sc_cnt);
        SYS_AT_ENCODE_BUF_STATS_MSG_SC(0, CTC_EGRESS, sc_cnt.scCnt0, 1);
        SYS_AT_ENCODE_BUF_STATS_MSG_SC(1, CTC_EGRESS, sc_cnt.scCnt1, 1);
        SYS_AT_ENCODE_BUF_STATS_MSG_SC(2, CTC_EGRESS, sc_cnt.scCnt2, 1);
        SYS_AT_ENCODE_BUF_STATS_MSG_SC(3, CTC_EGRESS, sc_cnt.scCnt3, 1);


        cmd = DRV_IOR(DsErmScCntMc_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &sc_egs_cnt_mc);
        SYS_AT_ENCODE_BUF_STATS_MSG_SC(0, CTC_EGRESS, sc_egs_cnt_mc.scCnt0, 0);
        SYS_AT_ENCODE_BUF_STATS_MSG_SC(1, CTC_EGRESS, sc_egs_cnt_mc.scCnt1, 0);
        SYS_AT_ENCODE_BUF_STATS_MSG_SC(2, CTC_EGRESS, sc_egs_cnt_mc.scCnt2, 0);
        SYS_AT_ENCODE_BUF_STATS_MSG_SC(3, CTC_EGRESS, sc_egs_cnt_mc.scCnt3, 0);
    }
    if (p_usw_monitor_master[lchip]->buf_scan->round_trip_en)
    {
        cmd = DRV_IOR(DsIrmHeadroomCnt_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &field_val);
        SYS_AT_ENCODE_BUF_STATS_MSG(CTC_MONITOR_BUFFER_ROUND_TRIP, CTC_INGRESS, field_val, 1);
    }
    return CTC_E_NONE;
}

int32
sys_at_monitor_sync_buffer_stats(uint8 lchip, void* p_data)
{
    ctc_monitor_data_t  monitor_data;
    sys_dma_reg_t* p_dma_reg = (sys_dma_reg_t*)p_data;
    sys_dma_sync_tbl_t* p_tbl =  (sys_dma_sync_tbl_t*)p_dma_reg->p_ext;
    uint32 ii = 0;
    uint32 idx = 0;
    ctc_monitor_msg_t*  p_msg;
    uint8 gchip = 0;
    uint64 ts = (uint64)p_tbl->ts[1] << 32 | p_tbl->ts[0];
    uint16 channel_id;
    uint16 lport;
    uint32 gport;
    mon_buf_cnt_at_t* p_cnt;
    mon_mc_queue_buf_cnt_at_t* p_cnt_mc;

    CTC_ERROR_RETURN(sys_usw_get_gchip_id(lchip, &gchip));
    sal_memset(&monitor_data, 0, sizeof(ctc_monitor_data_t));
    monitor_data.p_msg = p_usw_monitor_master[lchip]->p_buffer_stats;

    /*must at first*/
    if (p_tbl->first_sync)
    {
        sys_at_monitor_sync_global_buffer_stats(lchip, gchip, &monitor_data, p_tbl, ts);
    }
    p_msg = monitor_data.p_msg + monitor_data.msg_num;

    switch (p_tbl->tbl_id)
    {
        case DsIrmPortCntUc_t:/*DP*/
        case DsIrmPortCntMc_t:/*DP*/
            if (!p_usw_monitor_master[lchip]->buf_scan->port_en_igs)
            {
                break;
            }

            for (ii = 0; ii < MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM); ii++)
            {
                sys_usw_get_channel_by_sub_chan(lchip + p_tbl->pp_id, p_tbl->dp_id & 0x1,
                                                ii,
                                                &channel_id);
                /*Need mapping from channel to lport*/
                lport = SYS_MAP_SYS_LPORT_TO_DRV_LPORT(SYS_GET_LPORT_ID_WITH_CHAN(lchip, 0, channel_id));
                if (!p_usw_monitor_master[lchip]->buf_scan->port[lport].port_en_igs)
                {
                    continue;
                }
                p_cnt = (mon_buf_cnt_at_t*)p_dma_reg->p_data + ii;
                SYS_AT_ENCODE_BUF_STATS_MSG_PORT(CTC_MAP_LPORT_TO_GPORT(gchip, lport), CTC_INGRESS, p_cnt->count, (p_tbl->tbl_id == DsIrmPortCntUc_t));
                SYS_AT_BUFFER_STATS_REPORT(1);
            }
            break;
        case DsErmPortCntMc_t:/*CORE*/
            if (!p_usw_monitor_master[lchip]->buf_scan->port_en_egs)
            {
                break;
            }
            for (ii = 0; ii < MCHIP_CAP(SYS_CAP_NETWORK_CHANNEL_NUM); ii++)
            {
                sys_usw_get_channel_by_sub_chan(lchip + ii/(MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM) * 2),
                                                        (ii / MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM)) & 0x1 ,
                                                        ii%MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM),
                                                        &channel_id);
                /*Need mapping from channel to lport*/
                lport = SYS_MAP_SYS_LPORT_TO_DRV_LPORT(SYS_GET_LPORT_ID_WITH_CHAN(lchip, 0, channel_id));
                if (!p_usw_monitor_master[lchip]->buf_scan->port[lport].port_en_egs)
                {
                    continue;
                }
                gport = CTC_MAP_LPORT_TO_GPORT(gchip, lport);
                p_cnt_mc = (mon_mc_queue_buf_cnt_at_t*)p_dma_reg->p_data + ii;
                p_tbl->pp_id = ii/(MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM) * 2);
                SYS_AT_ENCODE_BUF_STATS_MSG_PORT(gport, CTC_EGRESS, p_cnt_mc->g_0_queueCnt, 0);
                SYS_AT_BUFFER_STATS_REPORT(1);
            }
            break;
        case DsIrmPortTcCntUc_t:/*DP*/
        case DsIrmPortTcCntMc_t:/*DP*/
            if (!p_usw_monitor_master[lchip]->buf_scan->port_tc_en_igs)
            {
                break;
            }

            for (ii = 0; ii < MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM); ii++)
            {
                sys_usw_get_channel_by_sub_chan(lchip + p_tbl->pp_id, p_tbl->dp_id & 0x1,
                                                ii,
                                                &channel_id);
                /*Need mapping from channel to lport*/
                lport = SYS_MAP_SYS_LPORT_TO_DRV_LPORT(SYS_GET_LPORT_ID_WITH_CHAN(lchip, 0, channel_id));
                if (!p_usw_monitor_master[lchip]->buf_scan->port[lport].port_tc_en_igs)
                {
                    continue;
                }
                for (idx = 0; idx < SYS_AT_TC_NUM; idx++)/*loop tc*/
                {
                    p_cnt = (mon_buf_cnt_at_t*)p_dma_reg->p_data + ii * 8 + idx;
                    SYS_AT_ENCODE_BUF_STATS_MSG_PORT_TC(CTC_MAP_LPORT_TO_GPORT(gchip, lport), CTC_INGRESS, idx, p_cnt->count, (p_tbl->tbl_id == DsIrmPortTcCntUc_t));
                }
                SYS_AT_BUFFER_STATS_REPORT(SYS_AT_TC_NUM);
            }
            break;
        case DsIrmPortScCntUc_t:/*DP*/
        case DsIrmPortScCntMc_t:/*DP*/
            if (!p_usw_monitor_master[lchip]->buf_scan->port_sc_en_igs)
            {
                break;
            }

            for (ii = 0; ii < MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM); ii++)
            {
                sys_usw_get_channel_by_sub_chan(lchip + p_tbl->pp_id, p_tbl->dp_id & 0x1,
                                                ii,
                                                &channel_id);
                /*Need mapping from channel to lport*/
                lport = SYS_MAP_SYS_LPORT_TO_DRV_LPORT(SYS_GET_LPORT_ID_WITH_CHAN(lchip, 0, channel_id));
                if (!p_usw_monitor_master[lchip]->buf_scan->port[lport].port_sc_en_igs)
                {
                    continue;
                }
                for (idx = 0; idx < 4; idx++)/*loop sc*/
                {
                    p_cnt = (mon_buf_cnt_at_t*)p_dma_reg->p_data + ii * 4 + idx;
                    SYS_AT_ENCODE_BUF_STATS_MSG_PORT_SC(CTC_MAP_LPORT_TO_GPORT(gchip, lport), CTC_INGRESS, idx, p_cnt->count, (p_tbl->tbl_id == DsIrmPortScCntUc_t));
                }
                SYS_AT_BUFFER_STATS_REPORT(4);
            }
            break;
        case DsErmPortScCntMc_t:/*CORE*/
            if (!p_usw_monitor_master[lchip]->buf_scan->port_sc_en_egs)
            {
                break;
            }
            for (ii = 0; ii < MCHIP_CAP(SYS_CAP_NETWORK_CHANNEL_NUM); ii++)
            {
                sys_usw_get_channel_by_sub_chan(lchip + ii/(MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM) * 2),
                                                        (ii / MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM)) & 0x1 ,
                                                        ii%MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM),
                                                        &channel_id);
                /*Need mapping from channel to lport*/
                lport = SYS_MAP_SYS_LPORT_TO_DRV_LPORT(SYS_GET_LPORT_ID_WITH_CHAN(lchip, 0, channel_id));
                if (!p_usw_monitor_master[lchip]->buf_scan->port[lport].port_sc_en_egs)
                {
                    continue;
                }
                gport = CTC_MAP_LPORT_TO_GPORT(gchip, lport);
                p_tbl->pp_id = ii/(MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM) * 2);
                for (idx = 0; idx < 4; idx++)
                {
                    p_cnt_mc = (mon_mc_queue_buf_cnt_at_t*)p_dma_reg->p_data + ii * 4 + idx;
                    SYS_AT_ENCODE_BUF_STATS_MSG_PORT_SC(CTC_MAP_LPORT_TO_GPORT(gchip, lport), CTC_EGRESS, idx, p_cnt_mc->g_0_queueCnt, 0);
                }
                SYS_AT_BUFFER_STATS_REPORT(4);
            }
            break;
        case DsErmPortTcCntUc_t:/*DP*/
            if (!p_usw_monitor_master[lchip]->buf_scan->port_tc_en_egs)
            {
                break;
            }
            for (ii = 0; ii < MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM); ii++)
            {
                sys_usw_get_channel_by_sub_chan(lchip + p_tbl->pp_id, p_tbl->dp_id & 0x1,
                                                ii,
                                                &channel_id);
                /*Need mapping from channel to lport*/
                lport = SYS_MAP_SYS_LPORT_TO_DRV_LPORT(SYS_GET_LPORT_ID_WITH_CHAN(lchip, 0, channel_id));
                if (!p_usw_monitor_master[lchip]->buf_scan->port[lport].port_tc_en_egs)
                {
                    continue;
                }
                for (idx = 0; idx < SYS_AT_TC_NUM; idx++)/*loop tc*/
                {
                    p_cnt = (mon_buf_cnt_at_t*)p_dma_reg->p_data + ii * 8 + idx;
                    SYS_AT_ENCODE_BUF_STATS_MSG_PORT_TC(CTC_MAP_LPORT_TO_GPORT(gchip, lport), CTC_EGRESS, idx, p_cnt->count, 1);
                }
                SYS_AT_BUFFER_STATS_REPORT(SYS_AT_TC_NUM);
            }
            break;
        case DsErmQueueCntMc_t: /*CORE*/
            if (!p_usw_monitor_master[lchip]->buf_scan->queue_en)
            {
                break;
            }
            {
                sys_at_monitor_que_buffer_param_t param;

                param.monitor_data = &monitor_data;
                param.p_msg = &p_msg;
                param.gchip = gchip;
                param.p_tbl = p_tbl;
                for (ii = 0; ii < MCHIP_CAP(SYS_CAP_NETWORK_CHANNEL_NUM); ii++)
                {
                    sys_usw_get_channel_by_sub_chan(lchip + ii/(MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM) * 2),
                                                        (ii / MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM)) & 0x1 ,
                                                        ii%MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM),
                                                        &channel_id);
                    /*Need mapping from channel to lport*/
                    lport = SYS_MAP_SYS_LPORT_TO_DRV_LPORT(SYS_GET_LPORT_ID_WITH_CHAN(lchip, 0, channel_id));
                    if (!p_usw_monitor_master[lchip]->buf_scan->port[lport].queue_en)
                    {
                        continue;
                    }
                    p_tbl->pp_id = ii/(MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM) * 2);
                    param.gport = CTC_MAP_LPORT_TO_GPORT(gchip, lport);
                    param.p_reg_base = (mon_mc_queue_buf_cnt_at_t*)p_dma_reg->p_data + (ii * SYS_AT_MC_Q_NUM);
                    sys_usw_queue_traverse_queue_node(lchip, lport, _sys_at_monitor_encode_port_mcq_buffer, &param);
                    SYS_AT_BUFFER_STATS_REPORT(SYS_AT_MC_Q_NUM);
                }
            }
            break;
        default:
            /*Do Nothing*/
            break;
    }
    /*CallBack*/
    if (p_usw_monitor_master[lchip]->func && monitor_data.msg_num)
    {
        p_usw_monitor_master[lchip]->func(&monitor_data, p_usw_monitor_master[lchip]->user_data);
    }
    return CTC_E_NONE;
}


int32
sys_at_monitor_buf_sync_interval(uint8 lchip, uint8 is_set, uint32* interval)
{
    CTC_PTR_VALID_CHECK(interval);
    if (is_set)
    {
        return sys_at_dma_set_monitor_buf_sync_time(lchip, *interval);
    }
    return sys_at_dma_get_monitor_buf_sync_time(lchip, interval);
}

#define SYS_AT_PROCESS_BUFFER_SCAN_PORT(F)                                              \
    p_usw_monitor_master[lchip]->buf_scan->port[lport].F = mon_cfg->value ? 1 : 0;      \
    if (mon_cfg->value)                                                                 \
    {                                                                                   \
        p_usw_monitor_master[lchip]->buf_scan->F = 1;                                   \
    } else {                                                                            \
        for (ii = 0; ii < MAX_PORT_NUM_PER_CHIP; ii++)                                  \
        {                                                                               \
            if (p_usw_monitor_master[lchip]->buf_scan->port[ii].F)                      \
            {                                                                           \
                valid = 1;                                                              \
                break;                                                                  \
            }                                                                           \
        }                                                                               \
        p_usw_monitor_master[lchip]->buf_scan->F = valid;                               \
    }

STATIC int32
_sys_at_monitor_set_buffer_scan(uint8 lchip, void* p_cfg)
{
    ctc_monitor_config_t* mon_cfg = (ctc_monitor_config_t*)p_cfg;
    sys_port_info_t port_info = {0};
    uint16 lport = CTC_MAP_GPORT_TO_LPORT(mon_cfg->gport);
    uint16 ii = 0;
    uint8 valid = 0;

    if(mon_cfg->dir == CTC_EGRESS &&
        (mon_cfg->buffer_type == CTC_MONITOR_BUFFER_PORT
        || mon_cfg->buffer_type == CTC_MONITOR_BUFFER_PORT_SC
        ||mon_cfg->buffer_type == CTC_MONITOR_BUFFER_QUEUE))
    {
        CTC_ERROR_RETURN(sys_usw_port_api_get_com_info(lchip, lport, 0, &port_info));
        if (!(SYS_DMPS_NETWORK_PORT == port_info.port_type || SYS_DMPS_CPU_MAC_PORT == port_info.port_type || SYS_DMPS_CPUMAC_NETWORK_PORT == port_info.port_type))
        {
            return CTC_E_INVALID_PORT;
        }
    }

    switch(mon_cfg->buffer_type)
    {
    case CTC_MONITOR_BUFFER_PORT:
        if(mon_cfg->dir == CTC_EGRESS)
        {
            SYS_AT_PROCESS_BUFFER_SCAN_PORT(port_en_egs);
        }
        else
        {
            SYS_AT_PROCESS_BUFFER_SCAN_PORT(port_en_igs);
        }

        break;
    case CTC_MONITOR_BUFFER_PORT_SC:
        if(mon_cfg->dir == CTC_EGRESS)
        {
            SYS_AT_PROCESS_BUFFER_SCAN_PORT(port_sc_en_egs);
        }
        else
        {
            SYS_AT_PROCESS_BUFFER_SCAN_PORT(port_sc_en_igs);
        }
        break;
    case CTC_MONITOR_BUFFER_PORT_PRIO_CLASS:
        if(mon_cfg->dir == CTC_EGRESS)
        {
            SYS_AT_PROCESS_BUFFER_SCAN_PORT(port_tc_en_egs);
        }
        else
        {
            SYS_AT_PROCESS_BUFFER_SCAN_PORT(port_tc_en_igs);
        }
        break;
    case CTC_MONITOR_BUFFER_SC:
        if(mon_cfg->dir == CTC_EGRESS)
        {
            p_usw_monitor_master[lchip]->buf_scan->sc_en_egs = mon_cfg->value ? 1 : 0;
        }
        else
        {
            p_usw_monitor_master[lchip]->buf_scan->sc_en_igs = mon_cfg->value ? 1 : 0;
        }
        break;
    case CTC_MONITOR_BUFFER_C2C:
        if(mon_cfg->dir == CTC_EGRESS)
        {
            p_usw_monitor_master[lchip]->buf_scan->c2c_en_egs = mon_cfg->value ? 1 : 0;
        }
        else
        {
            p_usw_monitor_master[lchip]->buf_scan->c2c_en_igs = mon_cfg->value ? 1 : 0;
        }
        break;
    case CTC_MONITOR_BUFFER_CONTROL:
        if(mon_cfg->dir == CTC_EGRESS)
        {
            p_usw_monitor_master[lchip]->buf_scan->critical_en_egs = mon_cfg->value ? 1 : 0;
        }
        else
        {
            p_usw_monitor_master[lchip]->buf_scan->critical_en_igs = mon_cfg->value ? 1 : 0;
        }
        break;
    case CTC_MONITOR_BUFFER_TOTAL:
        if(mon_cfg->dir == CTC_EGRESS)
        {
            p_usw_monitor_master[lchip]->buf_scan->total_en_egs = mon_cfg->value ? 1 : 0;
        }
        else
        {
            p_usw_monitor_master[lchip]->buf_scan->total_en_igs = mon_cfg->value ? 1 : 0;
        }
        break;

    case CTC_MONITOR_BUFFER_QUEUE:
        if(mon_cfg->dir == CTC_EGRESS)
        {
            SYS_AT_PROCESS_BUFFER_SCAN_PORT(queue_en);
        }
        else
        {
            return CTC_E_NOT_SUPPORT;
        }
        break;
    case CTC_MONITOR_BUFFER_SPAN:
        if(mon_cfg->dir == CTC_EGRESS)
        {
            p_usw_monitor_master[lchip]->buf_scan->span_en = mon_cfg->value ? 1 : 0;
        }
        else
        {
            return CTC_E_NOT_SUPPORT;
        }
        break;
    case CTC_MONITOR_BUFFER_ROUND_TRIP:
        if(mon_cfg->dir == CTC_INGRESS)
        {
            p_usw_monitor_master[lchip]->buf_scan->round_trip_en = mon_cfg->value ? 1 : 0;
        }
        else
        {
            return CTC_E_NOT_SUPPORT;
        }
        break;
    default:
        return CTC_E_INVALID_PARAM;
    }

    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_MONITOR, SYS_WB_APPID_MONITOR_SUBID_MASTER, 1);
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_MONITOR, SYS_WB_APPID_MONITOR_SUBID_BUFF_SCAN_CTL, 1);

    if(mon_cfg->dir == CTC_EGRESS &&
        (mon_cfg->buffer_type == CTC_MONITOR_BUFFER_PORT
        || mon_cfg->buffer_type == CTC_MONITOR_BUFFER_PORT_SC
        ||mon_cfg->buffer_type == CTC_MONITOR_BUFFER_QUEUE))
    {
        uint32 cmd = 0;
        uint32 field_val = 0;
        uint32  dp_id = 0;
        uint32  dp_chan = 0;
        ErmResrcStateInformScanCtl_m erm_scan_ctl;

        dp_chan = port_info.sub_chan_id;
        dp_id = port_info.dp_id;
        lchip = SYS_PP_BASE(lchip) + port_info.pp_id;
        cmd = DRV_IOR(ErmResrcStateInformScanCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &erm_scan_ctl));
        field_val = GetErmResrcStateInformScanCtl(V, resrcStateInformScanChanVec_f, &erm_scan_ctl);
        if(p_usw_monitor_master[lchip]->buf_scan->port[lport].port_en_egs
            || p_usw_monitor_master[lchip]->buf_scan->port[lport].port_sc_en_egs
            || p_usw_monitor_master[lchip]->buf_scan->port[lport].queue_en)
        {
            CTC_BIT_SET(field_val, dp_chan);
        }
        else
        {
            CTC_BIT_UNSET(field_val, dp_chan);
        }
        SetErmResrcStateInformScanCtl(V, resrcStateInformScanChanVec_f, &erm_scan_ctl, field_val);
        cmd = DRV_IOW(ErmResrcStateInformScanCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, dp_id), &erm_scan_ctl));
    }

    return CTC_E_NONE;
}


STATIC int32
_sys_at_monitor_get_buffer_scan(uint8 lchip, void* p_cfg)
{
    ctc_monitor_config_t* mon_cfg = (ctc_monitor_config_t*)p_cfg;
    uint16 lport = CTC_MAP_GPORT_TO_LPORT(mon_cfg->gport);
    switch(mon_cfg->buffer_type)
    {
    case CTC_MONITOR_BUFFER_PORT:
        if(mon_cfg->dir == CTC_EGRESS)
        {
            mon_cfg->value = p_usw_monitor_master[lchip]->buf_scan->port[lport].port_en_egs;
        }
        else
        {
            mon_cfg->value = p_usw_monitor_master[lchip]->buf_scan->port[lport].port_en_igs;
        }

        break;
    case CTC_MONITOR_BUFFER_PORT_SC:
        if(mon_cfg->dir == CTC_EGRESS)
        {
            mon_cfg->value = p_usw_monitor_master[lchip]->buf_scan->port[lport].port_sc_en_egs;
        }
        else
        {
            mon_cfg->value = p_usw_monitor_master[lchip]->buf_scan->port[lport].port_sc_en_igs;
        }
        break;
    case CTC_MONITOR_BUFFER_PORT_PRIO_CLASS:
        if(mon_cfg->dir == CTC_EGRESS)
        {
            mon_cfg->value = p_usw_monitor_master[lchip]->buf_scan->port[lport].port_tc_en_egs;
        }
        else
        {
            mon_cfg->value = p_usw_monitor_master[lchip]->buf_scan->port[lport].port_tc_en_igs;
        }
        break;
    case CTC_MONITOR_BUFFER_SC:
        if(mon_cfg->dir == CTC_EGRESS)
        {
            mon_cfg->value = p_usw_monitor_master[lchip]->buf_scan->sc_en_egs;
        }
        else
        {
            mon_cfg->value = p_usw_monitor_master[lchip]->buf_scan->sc_en_igs;
        }
        break;
    case CTC_MONITOR_BUFFER_C2C:
        if(mon_cfg->dir == CTC_EGRESS)
        {
            mon_cfg->value = p_usw_monitor_master[lchip]->buf_scan->c2c_en_egs;
        }
        else
        {
            mon_cfg->value = p_usw_monitor_master[lchip]->buf_scan->c2c_en_igs;
        }
        break;
    case CTC_MONITOR_BUFFER_CONTROL:
        if(mon_cfg->dir == CTC_EGRESS)
        {
            mon_cfg->value = p_usw_monitor_master[lchip]->buf_scan->critical_en_egs;
        }
        else
        {
            mon_cfg->value = p_usw_monitor_master[lchip]->buf_scan->critical_en_igs;
        }
        break;
    case CTC_MONITOR_BUFFER_TOTAL:
        if(mon_cfg->dir == CTC_EGRESS)
        {
            mon_cfg->value = p_usw_monitor_master[lchip]->buf_scan->total_en_egs;
        }
        else
        {
            mon_cfg->value = p_usw_monitor_master[lchip]->buf_scan->total_en_igs;
        }
        break;

    case CTC_MONITOR_BUFFER_QUEUE:
        if(mon_cfg->dir == CTC_EGRESS)
        {
            mon_cfg->value = p_usw_monitor_master[lchip]->buf_scan->queue_en;
        }
        else
        {
            return CTC_E_NOT_SUPPORT;
        }
        break;
    case CTC_MONITOR_BUFFER_SPAN:
        if(mon_cfg->dir == CTC_EGRESS)
        {
            mon_cfg->value = p_usw_monitor_master[lchip]->buf_scan->span_en;
        }
        else
        {
            return CTC_E_NOT_SUPPORT;
        }
        break;
    case CTC_MONITOR_BUFFER_ROUND_TRIP:
        if(mon_cfg->dir == CTC_INGRESS)
        {
            mon_cfg->value = p_usw_monitor_master[lchip]->buf_scan->round_trip_en;
        }
        else
        {
            return CTC_E_NOT_SUPPORT;
        }
        break;
    default:
        return CTC_E_INVALID_PARAM;
    }
    return CTC_E_NONE;
}

int32
sys_at_monitor_buffer_scan(uint8 lchip, uint8 is_set, void* p_cfg)
{
    if (is_set)
    {
        return _sys_at_monitor_set_buffer_scan(lchip, p_cfg);
    }
    return _sys_at_monitor_get_buffer_scan(lchip, p_cfg);
}

STATIC int32
_sys_at_monitor_get_buffer_watermark(uint8 lchip, ctc_monitor_watermark_t *p_watermark)
{
    uint32 cmd = 0;
    uint32 step = 0;
    uint32 total_cnt = 0;
    uint32 index = 0;
    uint16 lport = 0;
    sys_port_info_t port_info = {0};
    sys_usw_dmps_port_info_t dmps_port_info = {0};

    sal_memset(&port_info, 0, sizeof(port_info));
    dmps_port_info.gport = p_watermark->gport;
    SYS_MONITOR_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    if(!((p_watermark->u.buffer.buffer_type == CTC_MONITOR_BUFFER_PORT
        || p_watermark->u.buffer.buffer_type == CTC_MONITOR_BUFFER_PORT_PRIO_CLASS
        || p_watermark->u.buffer.buffer_type == CTC_MONITOR_BUFFER_PORT_SC
        || p_watermark->u.buffer.buffer_type == CTC_MONITOR_BUFFER_QUEUE) && CTC_INGRESS == p_watermark->u.buffer.dir))
    {
        CTC_MAX_VALUE_CHECK(p_watermark->u.buffer.pp_id, SYS_PP_NUM(lchip) - 1);
    }

    if (p_watermark->u.buffer.buffer_type == CTC_MONITOR_BUFFER_PORT
        || p_watermark->u.buffer.buffer_type == CTC_MONITOR_BUFFER_PORT_PRIO_CLASS
        || p_watermark->u.buffer.buffer_type == CTC_MONITOR_BUFFER_PORT_SC)
    {
        if (CTC_GPORT_TYPE(p_watermark->gport) == CTC_GPORT_TYPE_CPU_MAC)
        {
            uint32 value = 0;
            CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_SUB_CHAN_ID, &value));
            port_info.sub_chan_id = value;
            CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_PP_ID, &value));
            port_info.pp_id = value;
            CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_DP_ID, &value));
            port_info.dp_id = value;
        }
        else
        {
            SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(p_watermark->gport, lchip, lport);
            if (!SYS_GPORT_IS_NETWORK_PORT(p_watermark->gport))
            {
                return CTC_E_INVALID_PORT;
            }
            CTC_ERROR_RETURN(sys_usw_port_api_get_com_info(lchip, lport, CTC_MAP_GPORT_TO_MCHAN_IDX(p_watermark->gport), &port_info));
        }
        lchip = SYS_PP_BASE(lchip) + port_info.pp_id;
    }
    else
    {
        lchip = SYS_PP_BASE(lchip) + p_watermark->u.buffer.pp_id;
    }

    switch (p_watermark->u.buffer.buffer_type)
    {
    case CTC_MONITOR_BUFFER_PORT:
        index = port_info.sub_chan_id;
        if (CTC_EGRESS == p_watermark->u.buffer.dir)
        {
            CTC_ERROR_RETURN(sys_at_qos_get_corss_core_lchip(&lchip, port_info.pp_id, p_watermark->u.buffer.pp_id));
            index += sys_at_qos_get_corss_core_tbl_idx(lchip, port_info.pp_id, p_watermark->u.buffer.pp_id, DRV_INS(1, 0));
            cmd = DRV_IOR(DsErmPortCntUcMax_t, DsErmPortCntUcMax_portCnt_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, port_info.dp_id), &total_cnt));
        }
        else
        {
            cmd = DRV_IOR(DsIrmPortCntUcMax_t, DsIrmPortCntUcMax_portCnt_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, port_info.dp_id), &total_cnt));
        }
        break;
    case CTC_MONITOR_BUFFER_C2C:
        if (CTC_EGRESS == p_watermark->u.buffer.dir)
        {
            cmd = DRV_IOR(DsErmMiscCntUcMax_t, DsErmMiscCntUcMax_c2cCnt_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &total_cnt));
        }
        else
        {
            cmd = DRV_IOR(DsIrmMiscCntUcMax_t, DsIrmMiscCntUcMax_c2cCnt_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &total_cnt));
        }
        break;
    case CTC_MONITOR_BUFFER_CONTROL:
        if (CTC_EGRESS == p_watermark->u.buffer.dir)
        {
            cmd = DRV_IOR(DsErmMiscCntUcMax_t, DsErmMiscCntUcMax_criticalCnt_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &total_cnt));
        }
        else
        {
            cmd = DRV_IOR(DsIrmMiscCntUcMax_t, DsIrmMiscCntUcMax_criticalCnt_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &total_cnt));
        }
        break;
    case CTC_MONITOR_BUFFER_TOTAL:
        if (CTC_EGRESS == p_watermark->u.buffer.dir)
        {
            cmd = DRV_IOR(DsErmMiscCntUcMax_t, DsErmMiscCntUcMax_totalCnt_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &total_cnt));
        }
        else
        {
            cmd = DRV_IOR(DsIrmMiscCntUcMax_t, DsIrmMiscCntUcMax_totalCnt_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &total_cnt));
        }
        break;

    case CTC_MONITOR_BUFFER_SC:
        CTC_MAX_VALUE_CHECK(p_watermark->u.buffer.sc, 3);
        if (CTC_EGRESS == p_watermark->u.buffer.dir)
        {
            step = DsErmScCntUcMax_g_1_scCnt_f - DsErmScCntUcMax_g_0_scCnt_f;
            cmd = DRV_IOR(DsErmScCntUcMax_t, DsErmScCntUcMax_g_0_scCnt_f + step * p_watermark->u.buffer.sc);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &total_cnt));
        }
        else
        {
            step = DsIrmScCntUcMax_g_1_scCnt_f - DsIrmScCntUcMax_g_0_scCnt_f;
            cmd = DRV_IOR(DsIrmScCntUcMax_t, DsIrmScCntUcMax_g_0_scCnt_f + step * p_watermark->u.buffer.sc);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &total_cnt));
        }
        break;
    case CTC_MONITOR_BUFFER_QUEUE:
        if (CTC_EGRESS == p_watermark->u.buffer.dir)
        {
            CTC_ERROR_RETURN(sys_at_qos_queue_get_buffer_watermark(lchip, p_watermark->u.buffer.pp_id, &(p_watermark->queue), &total_cnt));
        }
        else
        {
            return CTC_E_NOT_SUPPORT;
        }
        break;
    case CTC_MONITOR_BUFFER_PORT_PRIO_CLASS:
        CTC_MAX_VALUE_CHECK(p_watermark->u.buffer.sc, 7); /*reused as priority class*/
        if (CTC_EGRESS == p_watermark->u.buffer.dir)
        {
            return CTC_E_NOT_SUPPORT;
        }
        else
        {
            cmd = DRV_IOR(DsIrmPortTcCntUcMax_t, DsIrmPortTcCntUcMax_portTcCnt_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, port_info.sub_chan_id << 3 | p_watermark->u.buffer.sc, DRV_CMD_DP_EN(cmd, port_info.dp_id), &total_cnt));
        }
        break;
    case CTC_MONITOR_BUFFER_PORT_SC:
        CTC_MAX_VALUE_CHECK(p_watermark->u.buffer.sc, 3); /*reused as priority class*/
        index = port_info.sub_chan_id << 2 | p_watermark->u.buffer.sc;
        if (CTC_EGRESS == p_watermark->u.buffer.dir)
        {
            CTC_ERROR_RETURN(sys_at_qos_get_corss_core_lchip(&lchip, port_info.pp_id, p_watermark->u.buffer.pp_id));
            index += sys_at_qos_get_corss_core_tbl_idx(lchip, port_info.pp_id, p_watermark->u.buffer.pp_id, DRV_INS(1, 0));
            cmd = DRV_IOR(DsErmPortScCntUcMax_t, DsErmPortScCntUcMax_portScCnt_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, port_info.dp_id), &total_cnt));
        }
        else
        {
            cmd = DRV_IOR(DsIrmPortScCntUcMax_t, DsIrmPortScCntUcMax_portScCnt_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, port_info.dp_id), &total_cnt));
        }
        break;
    case CTC_MONITOR_BUFFER_ROUND_TRIP:
        if (CTC_EGRESS == p_watermark->u.buffer.dir)
        {
            return CTC_E_NOT_SUPPORT;
        }
        else
        {
            cmd = DRV_IOR(DsIrmHeadroomCntMax_t, DsIrmHeadroomCntMax_headroomCnt_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &total_cnt));
        }
        break;
    default:
        return CTC_E_INVALID_PARAM;
    }

    p_watermark->u.buffer.max_uc_cnt = total_cnt;
    p_watermark->u.buffer.max_total_cnt = total_cnt;

    return CTC_E_NONE;
}

STATIC int32
_sys_at_monitor_clear_buffer_watermark(uint8 lchip, ctc_monitor_watermark_t *p_watermark)
{
    uint32 cmd = 0;
    uint32 step = 0;
    uint32 field_value = 0;
    uint32 index = 0;
    uint16 lport = 0;
    sys_port_info_t port_info = {0};
    sys_usw_dmps_port_info_t dmps_port_info = {0};

    sal_memset(&port_info, 0, sizeof(port_info));
    dmps_port_info.gport = p_watermark->gport;
    SYS_MONITOR_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    if(!((p_watermark->u.buffer.buffer_type == CTC_MONITOR_BUFFER_PORT
        || p_watermark->u.buffer.buffer_type == CTC_MONITOR_BUFFER_PORT_PRIO_CLASS
        || p_watermark->u.buffer.buffer_type == CTC_MONITOR_BUFFER_PORT_SC
        || p_watermark->u.buffer.buffer_type == CTC_MONITOR_BUFFER_QUEUE) && CTC_INGRESS == p_watermark->u.buffer.dir))
    {
        CTC_MAX_VALUE_CHECK(p_watermark->u.buffer.pp_id, SYS_PP_NUM(lchip) - 1);
    }

    if (p_watermark->u.buffer.buffer_type == CTC_MONITOR_BUFFER_PORT
    || p_watermark->u.buffer.buffer_type == CTC_MONITOR_BUFFER_PORT_PRIO_CLASS
    || p_watermark->u.buffer.buffer_type == CTC_MONITOR_BUFFER_PORT_SC)
    {
        if (CTC_GPORT_TYPE(p_watermark->gport) == CTC_GPORT_TYPE_CPU_MAC)
        {
            uint32 value = 0;
            CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_SUB_CHAN_ID, &value));
            port_info.sub_chan_id = value;
            CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_PP_ID, &value));
            port_info.pp_id = value;
            CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_DP_ID, &value));
            port_info.dp_id = value;
        }
        else
        {
            SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(p_watermark->gport, lchip, lport);
            if (!SYS_GPORT_IS_NETWORK_PORT(p_watermark->gport))
            {
                return CTC_E_INVALID_PORT;
            }
            CTC_ERROR_RETURN(sys_usw_port_api_get_com_info(lchip, lport, CTC_MAP_GPORT_TO_MCHAN_IDX(p_watermark->gport), &port_info));
        }
        lchip = SYS_PP_BASE(lchip) + port_info.pp_id;
    }
    else
    {
        lchip = SYS_PP_BASE(lchip) + p_watermark->u.buffer.pp_id;
    }

    switch (p_watermark->u.buffer.buffer_type)
    {
    case CTC_MONITOR_BUFFER_PORT:
        index = port_info.sub_chan_id;
        if (CTC_EGRESS == p_watermark->u.buffer.dir)
        {
            CTC_ERROR_RETURN(sys_at_qos_get_corss_core_lchip(&lchip, port_info.pp_id, p_watermark->u.buffer.pp_id));
            index += sys_at_qos_get_corss_core_tbl_idx(lchip, port_info.pp_id, p_watermark->u.buffer.pp_id, DRV_INS(1, 0));

            cmd = DRV_IOW(DsErmPortCntUcMax_t, DsErmPortCntUcMax_portCnt_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, port_info.dp_id), &field_value));
        }
        else
        {
            cmd = DRV_IOW(DsIrmPortCntUcMax_t, DsIrmPortCntUcMax_portCnt_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, port_info.dp_id), &field_value));
        }
        break;
    case CTC_MONITOR_BUFFER_C2C:
        if (CTC_EGRESS == p_watermark->u.buffer.dir)
        {
            cmd = DRV_IOW(DsErmMiscCntUcMax_t, DsErmMiscCntUcMax_c2cCnt_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &field_value));
        }
        else
        {
            cmd = DRV_IOW(DsIrmMiscCntUcMax_t, DsIrmMiscCntUcMax_c2cCnt_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &field_value));
        }
        break;
    case CTC_MONITOR_BUFFER_CONTROL:
        if (CTC_EGRESS == p_watermark->u.buffer.dir)
        {
            cmd = DRV_IOW(DsErmMiscCntUcMax_t, DsErmMiscCntUcMax_criticalCnt_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &field_value));
        }
        else
        {
            cmd = DRV_IOW(DsIrmMiscCntUcMax_t, DsIrmMiscCntUcMax_criticalCnt_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &field_value));
        }
        break;
    case CTC_MONITOR_BUFFER_TOTAL:
        if (CTC_EGRESS == p_watermark->u.buffer.dir)
        {
            cmd = DRV_IOW(DsErmMiscCntUcMax_t, DsErmMiscCntUcMax_totalCnt_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &field_value));
        }
        else
        {
            cmd = DRV_IOW(DsIrmMiscCntUcMax_t, DsIrmMiscCntUcMax_totalCnt_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &field_value));
        }
        break;

    case CTC_MONITOR_BUFFER_SC:
        CTC_MAX_VALUE_CHECK(p_watermark->u.buffer.sc, 3);
        if (CTC_EGRESS == p_watermark->u.buffer.dir)
        {

            step = DsErmScCntUcMax_g_1_scCnt_f - DsErmScCntUcMax_g_0_scCnt_f;
            cmd = DRV_IOW(DsErmScCntUcMax_t, DsErmScCntUcMax_g_0_scCnt_f + step * p_watermark->u.buffer.sc);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &field_value));
        }
        else
        {
            step = DsIrmScCntUcMax_g_1_scCnt_f - DsIrmScCntUcMax_g_0_scCnt_f;
            cmd = DRV_IOW(DsIrmScCntUcMax_t, DsIrmScCntUcMax_g_0_scCnt_f + step * p_watermark->u.buffer.sc);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &field_value));
        }
        break;
    case CTC_MONITOR_BUFFER_QUEUE:
        if (CTC_EGRESS == p_watermark->u.buffer.dir)
        {
            CTC_ERROR_RETURN(sys_at_qos_queue_clear_buffer_watermark(lchip, p_watermark->u.buffer.pp_id, &(p_watermark->queue)));
        }
        else
        {
            return CTC_E_NOT_SUPPORT;
        }
        break;
    case CTC_MONITOR_BUFFER_PORT_PRIO_CLASS:
        CTC_MAX_VALUE_CHECK(p_watermark->u.buffer.sc, 7); /*reused as priority class*/
        if (CTC_EGRESS == p_watermark->u.buffer.dir)
        {
            return CTC_E_NOT_SUPPORT;
        }
        else
        {
            cmd = DRV_IOW(DsIrmPortTcCntUcMax_t, DsIrmPortTcCntUcMax_portTcCnt_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, port_info.sub_chan_id << 3 | p_watermark->u.buffer.sc, DRV_CMD_DP_EN(cmd, port_info.dp_id), &field_value));
        }
        break;
    case CTC_MONITOR_BUFFER_PORT_SC:
        CTC_MAX_VALUE_CHECK(p_watermark->u.buffer.sc, 3); /*reused as priority class*/
        index = port_info.sub_chan_id << 2 | p_watermark->u.buffer.sc;
        if (CTC_EGRESS == p_watermark->u.buffer.dir)
        {
            CTC_ERROR_RETURN(sys_at_qos_get_corss_core_lchip(&lchip, port_info.pp_id, p_watermark->u.buffer.pp_id));
            index += sys_at_qos_get_corss_core_tbl_idx(lchip, port_info.pp_id, p_watermark->u.buffer.pp_id, DRV_INS(1, 0));
            cmd = DRV_IOW(DsErmPortScCntUcMax_t, DsErmPortScCntUcMax_portScCnt_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, port_info.dp_id), &field_value));
        }
        else
        {
            cmd = DRV_IOW(DsIrmPortScCntUcMax_t, DsIrmPortScCntUcMax_portScCnt_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, DRV_CMD_DP_EN(cmd, port_info.dp_id), &field_value));
        }
        break;
    case CTC_MONITOR_BUFFER_ROUND_TRIP:
        if (CTC_EGRESS == p_watermark->u.buffer.dir)
        {
            return CTC_E_NOT_SUPPORT;
        }
        else
        {
            cmd = DRV_IOW(DsIrmHeadroomCntMax_t, DsIrmHeadroomCntMax_headroomCnt_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &field_value));
        }
        break;
    default:
        return CTC_E_INVALID_PARAM;
    }

    return CTC_E_NONE;
}


int32
sys_at_monitor_op_buffer_watermark(uint8 lchip, void* p_data, uint8 is_clear)
{
    if (is_clear)
    {
        return _sys_at_monitor_clear_buffer_watermark(lchip, (ctc_monitor_watermark_t*)p_data);
    }
    return _sys_at_monitor_get_buffer_watermark(lchip, (ctc_monitor_watermark_t*)p_data);
}

STATIC int32
_sys_at_monitor_get_path_latency_ptr(uint8 lchip, void* p_mon_watermark, uint16* mon_ptr)
{
    uint32 cmd = 0;
    uint16 src_lport = 0;
    uint16 dst_lport = 0;
    uint32 src_viewid = 0;
    uint32 dst_viewid = 0;
    uint32 path_mon_mode = 0;
    uint8  queue_id = 0;
    ctc_qos_queue_id_t queue;
    ctc_monitor_watermark_t* p_watermark = (ctc_monitor_watermark_t*)p_mon_watermark;

    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(p_watermark->src_gport, lchip, src_lport);
    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(p_watermark->gport, lchip, dst_lport);
    CTC_MAX_VALUE_CHECK(p_watermark->queue.class_prio, SYS_QUEUE_SUB_NODE_NUM-1);

    sal_memset(&queue, 0, sizeof(queue));
    *mon_ptr = 0xFFFF;
    queue.queue_type = CTC_QUEUE_TYPE_NETWORK_EGRESS;
    queue.gport = p_watermark->gport;
    queue.queue_id = p_watermark->queue.queue_id;
    queue.class_prio = p_watermark->queue.class_prio;
    CTC_ERROR_RETURN(sys_at_queue_get_queue_offset(lchip, &queue, &queue_id));

    cmd = DRV_IOR(EpePktProcPathMonCtl_t, EpePktProcPathMonCtl_pathMonMode_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &path_mon_mode));

    cmd = DRV_IOR(DsPathViewSrcMap_t, DsPathViewSrcMap_viewId_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, src_lport, cmd, &src_viewid));

    cmd = DRV_IOR(DsPathViewDstMap_t, DsPathViewDstMap_viewId_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, dst_lport, cmd, &dst_viewid));

    switch (path_mon_mode)
    {
        case CTC_MONITOR_LATENCY_MODE_1:
            if (SYS_MONITOR_VIEWID_VALID_CHECK(src_viewid) && SYS_MONITOR_VIEWID_VALID_CHECK(dst_viewid))
            {
                *mon_ptr = (dst_viewid & 0x3F) << 6 | (src_viewid & 0x3F);
            }
            break;

        case CTC_MONITOR_LATENCY_MODE_2:
            if (SYS_MONITOR_VIEWID_VALID_CHECK(dst_viewid))
            {
                *mon_ptr = ((queue_id & 0x8) >> 3) << 12 | dst_lport << 3 | (queue_id & 0x7);
            }
            break;
        case CTC_MONITOR_LATENCY_MODE_3:
            if (SYS_MONITOR_VIEWID_VALID_CHECK(src_viewid))
            {
                *mon_ptr = ((queue_id & 0x8) >> 3) << 12 | src_lport << 3 | (queue_id & 0x7);
            }
            break;
        case CTC_MONITOR_LATENCY_MODE_4:
            return CTC_E_NOT_SUPPORT;
            break;
        case CTC_MONITOR_LATENCY_MODE_5:
            if (SYS_MONITOR_VIEWID_VALID_CHECK(src_viewid) && SYS_MONITOR_VIEWID_VALID_CHECK(dst_viewid))
            {
                *mon_ptr = ((queue_id & 0x8) >> 3) << 12 | (src_viewid & 0x1F) << 7 | (dst_viewid & 0xF) << 3 | (queue_id & 0x7);
            }
            break;
        case CTC_MONITOR_LATENCY_MODE_6:
            if (SYS_MONITOR_VIEWID_VALID_CHECK(src_viewid) && SYS_MONITOR_VIEWID_VALID_CHECK(dst_viewid))
            {
                *mon_ptr = ((queue_id & 0x8) >> 3) << 12  | (dst_viewid & 0x1F) << 7 | (src_viewid & 0xF) << 3 | (queue_id & 0x7);
            }
            break;
        case CTC_MONITOR_LATENCY_MODE_7:
            if (SYS_MONITOR_VIEWID_VALID_CHECK(src_viewid) && SYS_MONITOR_VIEWID_VALID_CHECK(dst_viewid))
            {
                *mon_ptr = (dst_viewid & 0x1F) << 8 | (src_viewid & 0x1F) << 3 | (queue_id & 0x7);
            }
            break;

        case CTC_MONITOR_LATENCY_MODE_8:
            if (SYS_MONITOR_VIEWID_VALID_CHECK(src_viewid) && SYS_MONITOR_VIEWID_VALID_CHECK(dst_viewid))
            {
                *mon_ptr = (src_viewid & 0x1F) << 8 | (dst_viewid & 0x1F) << 3 | (queue_id & 0x7);
            }
            break;

        default:
            break;
    }

    if (0xFFFF == *mon_ptr)
    {
        return CTC_E_INVALID_PARAM;
    }

    SYS_MONITOR_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "monitor ptr = %d\n", *mon_ptr);
    return CTC_E_NONE;
}

int32
sys_at_monitor_get_path_latency_watermark(uint8 lchip, void* p_mon_watermark, uint16 channel_id)
{
    uint32 cmd = 0;
    uint32 field_value = 0;
    uint16 mon_ptr = 0;
    uint16 idx1 = 0;
    uint16 idx2 = 0;
    uint8  step = 0;
    ds_t ds;
    ctc_monitor_watermark_t* p_watermark = (ctc_monitor_watermark_t* )p_mon_watermark;

     sal_memset(&ds, 0, sizeof(ds));
    cmd = DRV_IOR(EpePktProcPathMonCtl_t, EpePktProcPathMonCtl_legacyFeatureEn_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));
    if (field_value == 1)/*legacy mode,DsLatencyMon0 for cnt,DsLatencyMon1 for latency*/
    {
        cmd = DRV_IOR(DsLatencyMon1_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, channel_id, DRV_CMD_PP_EN(cmd), &ds));
        p_watermark->u.latency.max_latency = GetDsLatencyMon1(V, u_g1_0_latencyMax_f , &ds) << 5;
        p_watermark->u.latency.min_latency = GetDsLatencyMon1(V, u_g1_0_latencyMin_f , &ds) << 5;
    }
    else/*path monitor mode,DsLatencyMon0 and DsLatencyMon1 for latency*/
    {
        CTC_ERROR_RETURN(_sys_at_monitor_get_path_latency_ptr(lchip, p_watermark, &mon_ptr));

        idx1 = (mon_ptr & 0xFFF) >> 3;
        idx2 = mon_ptr & 0x7;
        step = DsLatencyMon0_u_g1_1_latencyMax_f - DsLatencyMon0_u_g1_0_latencyMax_f;

        if (!CTC_IS_BIT_SET(mon_ptr, 12))
        {
            cmd = DRV_IOR(DsLatencyMon0_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, idx1, DRV_CMD_PP_EN(cmd), &ds));
            p_watermark->u.latency.max_latency = GetDsLatencyMon0(V, u_g1_0_latencyMax_f + step * idx2, &ds) << 5;
            p_watermark->u.latency.min_latency = GetDsLatencyMon0(V, u_g1_0_latencyMin_f + step * idx2, &ds) << 5;
        }
        else
        {
            cmd = DRV_IOR(DsLatencyMon1_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, idx1, DRV_CMD_PP_EN(cmd), &ds));
            p_watermark->u.latency.max_latency = GetDsLatencyMon1(V, u_g1_0_latencyMax_f + step * idx2, &ds) << 5;
            p_watermark->u.latency.min_latency = GetDsLatencyMon1(V, u_g1_0_latencyMin_f + step * idx2, &ds) << 5;
        }

        SYS_MONITOR_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "mon table = %d, idx1 = %d, idx2 = %d\n", CTC_IS_BIT_SET(mon_ptr, 12), idx1, idx2);
    }

    return CTC_E_NONE;
}


int32
sys_at_monitor_clear_path_latency_watermark(uint8 lchip, void* p_watermark, uint16 channel_id)
{
    uint32 cmd = 0;
    uint32 field_value = 0;
    uint16 mon_ptr = 0;
    uint16 idx1 = 0;
    uint16 idx2 = 0;
    uint8  step = 0;
    ds_t ds;

    cmd = DRV_IOR(EpePktProcPathMonCtl_t, EpePktProcPathMonCtl_legacyFeatureEn_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));
    if (field_value == 1)/*legacy mode,DsLatencyMon0 for cnt,DsLatencyMon1 for latency*/
    {
        cmd = DRV_IOR(DsLatencyMon1_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, channel_id, DRV_CMD_PP_EN(cmd), &ds));
        SetDsLatencyMon1(V, u_g1_0_latencyMax_f , &ds, 0);
        SetDsLatencyMon1(V, u_g1_0_latencyMin_f , &ds, 0x3FF);
        cmd = DRV_IOW(DsLatencyMon1_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, channel_id, DRV_CMD_PP_EN(cmd), &ds));
    }
    else/*path monitor mode,DsLatencyMon0 and DsLatencyMon1 for latency*/
    {
        CTC_ERROR_RETURN(_sys_at_monitor_get_path_latency_ptr(lchip, p_watermark, &mon_ptr));

        idx1 = (mon_ptr & 0xFFF) >> 3;
        idx2 = mon_ptr & 0x7;
        step = DsLatencyMon0_u_g1_1_latencyMax_f - DsLatencyMon0_u_g1_0_latencyMax_f;

        if (!CTC_IS_BIT_SET(mon_ptr, 12))
        {
            cmd = DRV_IOR(DsLatencyMon0_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, idx1, DRV_CMD_PP_EN(cmd), &ds));
            SetDsLatencyMon0(V, u_g1_0_latencyMax_f + step * idx2, &ds, 0);
            SetDsLatencyMon0(V, u_g1_0_latencyMin_f + step * idx2, &ds, 0x3FF);
            cmd = DRV_IOW(DsLatencyMon0_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, idx1, DRV_CMD_PP_EN(cmd), &ds));
        }
        else
        {
            cmd = DRV_IOR(DsLatencyMon1_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, idx1, DRV_CMD_PP_EN(cmd), &ds));
            SetDsLatencyMon1(V, u_g1_0_latencyMax_f + step * idx2, &ds, 0);
            SetDsLatencyMon1(V, u_g1_0_latencyMin_f + step * idx2, &ds, 0x3FF);
            cmd = DRV_IOW(DsLatencyMon1_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, idx1, DRV_CMD_PP_EN(cmd), &ds));
        }

        SYS_MONITOR_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "mon table = %d, idx1 = %d, idx2 = %d\n", CTC_IS_BIT_SET(mon_ptr, 12), idx1, idx2);
    }
    return CTC_E_NONE;
}

int32
sys_at_monitor_snapshot_state_isr(uint8 lchip, uint32 intr, void* p_data)
{
    CTC_INTERRUPT_EVENT_FUNC event_cb;
    ctc_monitor_data_t info   = {0};
    ctc_monitor_msg_t  msg[8];
    ctc_monitor_msg_t*  p_msg = NULL;
    ds_t ds_shadow;
    ds_t ds;
    uint32 cmd = 0;
    uint32 buffer_cnt = 0;
    uint8  gchip = 0;
    uint8  dir   = (SYS_INTR_FUNC_BSR_IRM_MON == intr) ? CTC_INGRESS : CTC_EGRESS;

    sal_memset(msg, 0, sizeof(ctc_monitor_msg_t) * 8);
    CTC_ERROR_RETURN(sys_usw_get_gchip_id(lchip, &gchip));

    info.msg_num = 0;
    info.p_msg = msg;
    cmd = DRV_IOR(dir ? ErmResrcMonCtl_t : IrmResrcMonCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ds));

    cmd = DRV_IOR(dir ? DsErmScCntUcShadow_t : DsIrmScCntUcShadow_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ds_shadow));

    p_msg = &msg[info.msg_num];
    buffer_cnt = GetDsErmScCntUcShadow(V, g_0_scCnt_f, &ds_shadow);
    if (buffer_cnt > GetIrmResrcMonCtl(V, trigger_scCnt0_f, &ds))
    {
        SYS_AT_ENCODE_SNAPSHOT_BUF_STATS_MSG_SC(0, dir, buffer_cnt, 1);
    }

    buffer_cnt = GetDsErmScCntUcShadow(V, g_1_scCnt_f, &ds_shadow);
    if (buffer_cnt > GetIrmResrcMonCtl(V, trigger_scCnt1_f, &ds))
    {
        SYS_AT_ENCODE_SNAPSHOT_BUF_STATS_MSG_SC(1, dir, buffer_cnt, 1);
    }

    buffer_cnt = GetDsErmScCntUcShadow(V, g_2_scCnt_f, &ds_shadow);
    if (buffer_cnt > GetIrmResrcMonCtl(V, trigger_scCnt2_f, &ds))
    {
        SYS_AT_ENCODE_SNAPSHOT_BUF_STATS_MSG_SC(2, dir, buffer_cnt, 1);
    }

    buffer_cnt = GetDsErmScCntUcShadow(V, g_3_scCnt_f, &ds_shadow);
    if (buffer_cnt > GetIrmResrcMonCtl(V, trigger_scCnt3_f, &ds))
    {
        SYS_AT_ENCODE_SNAPSHOT_BUF_STATS_MSG_SC(3, dir, buffer_cnt, 1);
    }

    cmd = DRV_IOR(dir ?  DsErmMiscCntUcShadow_t : DsIrmMiscCntUcShadow_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ds_shadow));

    buffer_cnt = GetDsErmMiscCntUcShadow(V, totalCnt_f, &ds_shadow);
    if (buffer_cnt > GetIrmResrcMonCtl(V, trigger_totalCnt_f, &ds))
    {
        SYS_AT_ENCODE_SNAPSHOT_BUF_STATS_MSG(CTC_MONITOR_BUFFER_TOTAL, dir, buffer_cnt, 1);
    }

    buffer_cnt = GetDsErmMiscCntUcShadow(V, c2cCnt_f, &ds_shadow);
    if (buffer_cnt > GetIrmResrcMonCtl(V, trigger_c2cCnt_f, &ds))
    {
        SYS_AT_ENCODE_SNAPSHOT_BUF_STATS_MSG(CTC_MONITOR_BUFFER_C2C, dir, buffer_cnt, 1);
    }

    buffer_cnt = GetDsErmMiscCntUcShadow(V, criticalCnt_f, &ds_shadow);
    if (buffer_cnt > GetIrmResrcMonCtl(V, trigger_criticalCnt_f, &ds))
    {
        SYS_AT_ENCODE_SNAPSHOT_BUF_STATS_MSG(CTC_MONITOR_BUFFER_CONTROL, dir, buffer_cnt, 1);
    }

    if (CTC_INGRESS == dir)
    {
        cmd = DRV_IOR(IrmResrcMonHeadroomCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ds));

        cmd = DRV_IOR(DsIrmHeadroomCntShadow_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ds_shadow));

        buffer_cnt = GetDsIrmHeadroomCntShadow(V, headroomCnt_f, &ds_shadow);
        if (buffer_cnt > GetIrmResrcMonHeadroomCtl(V, trigger_headroomCnt_f, &ds))
        {
            SYS_AT_ENCODE_SNAPSHOT_BUF_STATS_MSG(CTC_MONITOR_BUFFER_ROUND_TRIP, dir, buffer_cnt, 1);
        }
    }

    /*CallBack*/
    CTC_ERROR_RETURN(sys_usw_interrupt_get_event_cb(lchip, CTC_EVENT_BUFFER_SNAPSHOT, &event_cb));
    if (event_cb && info.msg_num)
    {
        CTC_ERROR_RETURN(event_cb(gchip, &info));
    }
    return CTC_E_NONE;
}

#endif
#endif

